package tm.operations;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.ListIterator;

import tm.data.CategoriesDao;
import tm.data.DaoFactory;
import tm.data.DetailsDao;
import tm.data.MilestonesDao;
import tm.data.ProjectsDao;
import tm.data.TaskDao;
import tm.data.TaskManagerJDBCDao;
import tm.data.TaskdetailsDao;
import tm.data.TaskstatesDao;
import tm.data.UsersDao;
import tm.dto.Categories;
import tm.dto.Details;
import tm.dto.Projects;
import tm.dto.Taskdetails;
import tm.dto.TaskdetailsId;
import tm.dto.Tasks;
import tm.dto.Taskstates;
import tm.dto.Users;

public class TaskDetailOperations {

	
	static TaskManagerJDBCDao tmDao = TaskManagerJDBCDao.getInstance();
	ProjectsDao projDao = DaoFactory.getInstance().getProjectsDao();
	static UsersDao userDao = DaoFactory.getInstance().getUsersDao();
	static TaskDao taskDao = DaoFactory.getInstance().getTaskDao();
	static TaskstatesDao taskStatesDao = DaoFactory.getInstance().getTaskstatesDao();
	static CategoriesDao categoriesDao = DaoFactory.getInstance().getCategoriesDao();
	static DetailsDao detailsDao = DaoFactory.getInstance().getDetailsDao();
	static TaskdetailsDao taskDetailsDao = DaoFactory.getInstance().getTaskdetailsDao();
	
	/** Intent: Return a list of Projects Objects for given Users Object.
	 * Return empty Project list if user is not working on any Project.
	 * 
	 * This is supporting method to satisfy the requirement described in SRS Section 3.2.3.1 Use Case: List Tasks per Project.
	 * 
	 * @param Users Object
	 * @return List of Projects Objects
	 */
	public List getProjects(Users user){
		
		List projList = new ArrayList();

		List projIdList = tmDao.projectsDBQuery(user.getUserId());
		
		if (projIdList.size() == 0){
			System.out.println("No projects found..");
			return projList;
		}else {
			ListIterator projIdListIterator = projIdList.listIterator();
			while(projIdListIterator.hasNext()){
				int tempProjId = (Integer)projIdListIterator.next();
				Projects proj = (Projects) projDao.findById(tempProjId);
				projList.add(proj);
			}			
		}	
		return projList;
	}
	
	/** Intent:Return a list of Tasks Objects for given Users and Projects Object.
	 * Return empty Task list if no Tasks exist for given User and Project.
	 * 
	 * This is supporting method to satisfy the requirement described in SRS Section 3.2.3.1 Use Case: List Tasks per Project.
	 * 
	 * @param Users Object
	 * @param Projects Object
	 * @return List of Tasks Objects
	 */
	public List getTasksProjects(Users user, Projects proj){
		
		List taskList = new ArrayList();
		
		List taskIdList = tmDao.taskDBQuery(user.getUserId(), proj.getProjectId());
		if (taskIdList.size() == 0){
			System.out.println("No Tasks found..");
			return taskList;
		}else {
			ListIterator taskIdListIterator = taskIdList.listIterator();
			while(taskIdListIterator.hasNext()){
				int tempTaskId = (Integer)taskIdListIterator.next();
				Tasks task = (Tasks) taskDao.findById(tempTaskId);
				taskList.add(task);
			}
			
		}	
		return taskList;
	}
	
	/** Intent: Return a list of TaskDetails objects for given User/Projects/Tasks Object.
	 * Return empty TaskDetails list if no TaskDetails exists for give User/Project/Task Combination.
	 * 
	 * This method satisfies the requirement described in SRS Section 3.2.3.1 Use Case: List Details.
	 * 
	 * @param Users Object
	 * @param Projects Object
	 * @param Tasks Object
	 * @return List of Taskdetails Objects
	 */
	public List getTaskdetails(Users user, Projects proj, Tasks task) {
		List taskDetailList = new ArrayList();
		
		taskDetailList = tmDao.taskDetailsQuery(user.getUserId(), proj.getProjectId(), task.getTaskId());
		
		return taskDetailList;
	}
	
	/** Intent: Return a list of TaskStates objects. This method will be queried to populate the
	 *  combo-box on Edit/Update TaskDetails screen.
	 *  
	 *  This is supporting method to satisfy requirement 3.2.3.1 in SRS Use Case: New Details.
	 * 
	 * @return List of TaskStates Objects.
	 */
	public List getTaskStates(){
		List taskStates = new ArrayList();
		taskStates = taskStatesDao.findAll();
		return taskStates;
	}
	
	/** Intent: Return a list of Categories objects. This method will be queried to populate the
	 *  combo-box on Edit/Update TaskDetails screen.
	 *  
	 *  This is supporting method to satisfy requirement 3.2.3.1 in SRS Use Case: New Details.
	 * 
	 * @return List of Categories Objects.
	 */
	public List getCategories() {
		List categories = new ArrayList();
		categories = categoriesDao.findAll();
		return categories;
	}
	
	/** Intent: This method will delete the existing Taskdetail. This method will not return anything.
	 * 
	 *  This method satisfies the requirement described in SRS Section 3.2.3.1 Use Case: Delete Details.
	 *  
	 * @param Users object
	 * @param Tasks object
	 * @param Details object
	 * 
	 */
	public void deleteTaskDetails(Users user, Tasks task, Details detail) {
		
		tmDao.deleteTaskDetails(user, task, detail);
		
	}
	
	/** Intent: This method will update the existing Task Detail. Method will not return anything.
	 * 
	 * This method satisfies the requirement described in SRS Section 3.2.3.1 Use Case: Edit Details.
	 * 
	 * @param Users object
	 * @param Tasks object
	 * @param Details object
	 */
	public void updateTaskDetails(Users user, Tasks task, Details details){
		tmDao.updateTaskDetails(details);
	}
	
	/** Intent: This method will insert new Task Detail. Method will not return anything.
	 * 
	 * This method satisfies the requirement described in SRS Section 3.2.3.1 Use Case: New Details.
	 * 
	 * @param Users object
	 * @param Tasks object
	 * @param Details object
	 */
	public void insertTaskDetails(Users user, Tasks task, Details details){
		tmDao.insertTaskDetails(user, task, details);
	}
	
	/**
	 * Main Method is provided, so that methods in this class can be exercised.
	 * @param args
	 */
	public static void main(String[] args){
		
		TaskDetailOperations tdo = new TaskDetailOperations();
		//tdo.displayTaskDetails();
		//tdo.updateTaskDetails();
		//tdo.insertTaskDetails();
		
		// Following block of code will display Task Details.
		// /**
		{
			Users user = (Users)userDao.findById(9);
			List projList = tdo.getProjects(user);

			System.out.println("User "+user.getFirstName()+" is working on Following Projects.");
			ListIterator projListIt = projList.listIterator();
			while(projListIt.hasNext()){
				Projects proj = (Projects)projListIt.next();
				System.out.println(proj.getProjectName());
				System.out.println("Following Tasks user is working on above project");
				List taskList = tdo.getTasksProjects(user, proj);
				
				ListIterator taskListIt = taskList.listIterator();
				while(taskListIt.hasNext()){
					Tasks task = (Tasks)taskListIt.next();
					System.out.print("Task Desc: "+ task.getTaskDescription()+" ");
					System.out.print("Actual Time: "+task.getTimeActual()+ " ");
					System.out.println("Task Time Estimate: "+task.getTimeEstimate()+ " ");
					
					List taskDetails = tdo.getTaskdetails(user, proj, task);
					
					System.out.println("Following task detais are available..");
					ListIterator taskDetailsListIt = taskDetails.listIterator();
					while(taskDetailsListIt.hasNext()){
						Taskdetails td = (Taskdetails)taskDetailsListIt.next();
						Details dt = td.getDetails();
						String taskStateDesc = ((Taskstates)dt.getTaskstates()).getTaskStateDescription();
						String categoriesDesc = ((Categories)dt.getCategories()).getCatDescription();
						System.out.print("Detail Id: "+dt.getDetailId()+ " ");
						System.out.println("Detail Comment: "+dt.getComment());
						System.out.println("Detail TimeAmount: "+dt.getTimeAmount());
						System.out.print("TaskState Id: "+((Taskstates)dt.getTaskstates()).getTaskStateId());
						System.out.println("      TaskState Description: "+taskStateDesc);
						System.out.print("Categories Id:"+ ((Categories)dt.getCategories()).getCatId());
						System.out.println("      Categories Description: "+categoriesDesc);
										
					}
				}
			}
		}
		// */
		// Following block of code will update existing Task Details.
		/**
		{
			
			System.out.println("");
			System.out.println("---------------------");
			System.out.println("Let us Edit the TaskDetails ..");
			System.out.println("Editing TaskDetails for User Jennifer (User ID: 9)...");
			System.out.println("Working on Project -Project A:...");
			System.out.println("For Task #5:....");
			Users userUpdate = (Users) userDao.findById(9);
			Tasks taskUpdate = (Tasks) taskDao.findById(5);
			Taskstates ts = (Taskstates) taskStatesDao.findById(2);
			Categories cat = (Categories) categoriesDao.findById(2);
			Details detail = new Details();
			detail.setDetailId(2);
			detail.setComment("Update of Detail ID 2");
			detail.setTimeAmount(220);
			SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
			Date startDate = null;
			try {
				startDate = sf.parse("2009-06-12 18:20:32");
			} catch (ParseException e) {
				e.printStackTrace();
			}
			detail.setStartTimestamp(startDate);
			System.out.println("Start Timestamp:"+startDate);
			Date transDate = null;
			try {
				transDate = sf.parse("2009-07-30 11:13:49");
			} catch (ParseException e) {
				e.printStackTrace();
			}
			detail.setTransactionTimestamp(transDate);
			System.out.println("Transaction Timestamp:"+transDate);
			detail.setTaskstates(ts);
			detail.setCategories(cat);
			tmDao.updateTaskDetails(detail);
			//saveOrUpdateTaskDetails(userUpdate, taskUpdate, detail);
			
		}
		*/
		
		// Following block of code will insert new Task Details.
		/**
		{
			
			System.out.println("");
			System.out.println("---------------------");
			System.out.println("Let us Insert the new TaskDetails ..");
			System.out.println("Inserting new TaskDetails for User Jennifer (User ID: 9)...");
			System.out.println("Working on Project -Project A:...");
			System.out.println("For Task #5:....");
			Users userUpdate = (Users) userDao.findById(9);
			Tasks taskUpdate = (Tasks) taskDao.findById(5);
			Taskstates ts = (Taskstates) taskStatesDao.findById(3);
			Categories cat = (Categories) categoriesDao.findById(1);
			Details detail = new Details();
			detail.setDetailId(5);
			detail.setComment("Insert of Detail ID 5");
			detail.setTimeAmount(30);
			SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
			Date startDate = null;
			try {
				startDate = sf.parse("2008-05-11 01:30:00");
			} catch (ParseException e) {
				e.printStackTrace();
			}
			detail.setStartTimestamp(startDate);
			System.out.println("Start Timestamp:"+startDate);
			Date transDate = null;
			try {
				transDate = sf.parse("2008-06-29 14:20:29");
			} catch (ParseException e) {
				e.printStackTrace();
			}
			detail.setTransactionTimestamp(transDate);
			System.out.println("Transaction Timestamp:"+transDate);
			detail.setTaskstates(ts);
			detail.setCategories(cat);
			tmDao.insertTaskDetails(userUpdate, taskUpdate, detail);
			//saveOrUpdateTaskDetails(userUpdate, taskUpdate, detail);
			
		}
		*/
		
		// Following block of code will delete the existing Task Details.
		/**
		{
			System.out.println("");
			System.out.println("---------------------");
			System.out.println("Let us Delete the exiting TaskDetails ..");
			System.out.println("Deleting TaskDetails for User Jennifer (User ID: 9)...");
			System.out.println("Working on Project -Project A:...");
			System.out.println("For Task #5:....");
			Users userUpdate = (Users) userDao.findById(9);
			Tasks taskUpdate = (Tasks) taskDao.findById(5);
			Details detail = new Details();
			detail.setDetailId(5);
			tdo.deleteTaskDetails(userUpdate, taskUpdate, detail);
		}
		*/
	}
}
